<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>人物漫游</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    html,body{
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <script type="module">
    import * as THREE from 'three';
    import {scene, camera, renderer, loadFbx} from './src/universal.js'
    import { ground, cubes } from './src/building.js'
    import ModelAnimation from './src/animation.js'
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
    // 控制器实例化  参数：相机  绑定事件的元素
    const controls = new OrbitControls( camera, renderer.domElement );
    controls.enableDamping = true

    //设置场景背景颜色
    scene.background = new THREE.Color(0x87ceff)

    // 设置相机位置及看向
    camera.position.set(10, 20, 30)
    // camera.position.set(0, 0, 30)
    camera.lookAt(0,0,0)

    let modelAnimation, player

    // 加载模型
    const loadModel = async () => {
      const object = await loadFbx('./models/rp_nathan_animated_003_walking.fbx')
      object.scale.set(0.04, 0.04, 0.04) // 缩放模型
      console.log(object);
      player = object
      // 遍历给物体添加投影
      object.traverse(child => {
        if (child.isMesh) {
          child.castShadow = true
          // child.receiveShadow = true
        }
      })
      // 给模型添加动画
      modelAnimation = new ModelAnimation(object)
      // modelAnimation.start('Take 001')

      // 加入场景
      scene.add(object)

      // player.position.set(-5,0,-5)
      // const cameraDirection = new THREE.Vector3()   //默认z轴的负方向 相机朝向
      // const playerDirection = new THREE.Vector3() //默认z轴的正方向  人物朝向
      // camera.getWorldDirection(cameraDirection)
      // player.getWorldDirection(playerDirection)
      // console.log(cameraDirection, playerDirection);
      
    }
    loadModel()

    scene.add(ground, ...cubes)

    // 绑定键盘事件
    const keyPressed = {}
    let isJumping = false
    let isDancing = false
    window.addEventListener('keydown', (event) => {
      const keyCode = event.code.toUpperCase()
      if (keyCode === 'space' && !isJumping) {
        isJumping = true
        modelAnimation.updateAction('jump')
      }
      if (keyCode === 'keyj' && !isDancing) {
        isDancing = true
        modelAnimation.updateAction('flair')
      }
      keyPressed[keyCode] = true
    })
    window.addEventListener('keyup', (event) => {
      const keyCode = event.code.toUpperCase()
      if (keyCode === 'space' && isJumping) {
        setTimeout(() => {
          isJumping = false
        }, modelAnimation.getAnimationDuration('jump') * 800);
      }
      if (keyCode === 'keyk') {
        isDancing = false
      }
      keyPressed[keyCode] = false
      
      
    })
    
    // 更新人物动作
    const updateAnimation = () => {
      if(isJumping) return
      if(
        (keyPressed['shiftleft'] && keyPressed['keyw']) ||
        (keyPressed['shiftleft'] && keyPressed['keya']) ||
        (keyPressed['shiftleft'] && keyPressed['keys']) ||
        (keyPressed['shiftleft'] && keyPressed['keyd'])
      ){
        // 切换跑
        console.log('跑动作');
        modelAnimation.updateAction('run')

      }else if (keyPressed['keyw'] || keyPressed['keya'] || keyPressed['keys'] || keyPressed['keyd']) {
        console.log('切换动作');
        modelAnimation.updateAction('walk')
      }else if(keyPressed['space']){
        modelAnimation.updateAction('jump')
      }else{
        // 站立
        modelAnimation.updateAction('Idle')
      }
    }

    // 更新人物朝向--转向
    const updateLookAt = () => {
      const cameraDirection = new THREE.Vector3()
      camera.getWorldDirection(cameraDirection)
      // 计算人物朝向 
      let lookAtPostion = new THREE.Vector3()

      // 声明速度向量
      const velocity = new THREE.Vector3(0,0,0.06)
      const originalLength = velocity.length() //向量的长度可表示速度的大小

      if (keyPressed['keyw']) {  //向前
        lookAtPostion.set(
          player.position.x + cameraDirection.x,
          player.position.y,
          player.position.z + camera.position.z
        )
        player.lookAt(lookAtPostion)

        // 人物运动
        cameraDirection.y = 0
        // 归一化
        cameraDirection.normalize()
        // 将向量的方向设置为和原向量相同，但长度为originalLength
        cameraDirection.setLength(originalLength)
        player.position.add(cameraDirection)
      }else if (keyPressed['keys']) { //向后
        lookAtPostion.set(
          player.position.x - cameraDirection.x,
          player.position.y,
          player.position.z - camera.position.z
        )
        player.lookAt(lookAtPostion)

        // 人物运动
        cameraDirection.y = 0
        // 归一化
        cameraDirection.normalize()
        cameraDirection.setLength(originalLength)
        player.position.sub(cameraDirection)
      }else if (keyPressed['keya']) { //左
        const leftDirection = new THREE.Vector3(
          -cameraDirection.z,
          0,
          cameraDirection.x
        )
        lookAtPostion.set(
          player.position.x - leftDirection.x,
          player.position.y,
          player.position.z - leftDirection.z
        )
        player.lookAt(lookAtPostion)

        // 人物运动
        leftDirection.setLength(originalLength)
        // leftDirection.negate() 取反
        player.position.add(leftDirection.negate())
      }else if (keyPressed['keyd']) { //右
        const rightDirection = new THREE.Vector3(
          cameraDirection.z,
          0,
          -cameraDirection.x
        )
        lookAtPostion.set(
          player.position.x - rightDirection.x,
          player.position.y,
          player.position.z - rightDirection.z
        )
        player.lookAt(lookAtPostion)

        // 人物运动
        rightDirection.setLength(originalLength)
        // rightDirection.negate() 取反
        player.position.add(rightDirection.negate())
      }
    }

    const clock = new THREE.Clock()
    // 动画关键帧函数
    const animate = () => {
      const elapsedTime = clock.getDelta()
      if (modelAnimation) {
        modelAnimation.update(elapsedTime)
        // updateAnimation()
      }
      updateLookAt()
      renderer.render(scene, camera)
      window.requestAnimationFrame(animate)
    }
    window.requestAnimationFrame(animate)
  </script>
</body>
</html>